package org.az.netty_study.p03_nio组件之selector._4_多线程selector;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 多线程配合selector的服务器
 */
@Slf4j
public class MultiThreadServer {
    public static void main(String[] args) throws IOException {
        Thread.currentThread().setName("boss");
        Selector boss = Selector.open();
        ServerSocketChannel ssc = ServerSocketChannel.open();
        ssc.configureBlocking(false);
        ssc.bind(new InetSocketAddress(9995));
        ssc.register(boss, SelectionKey.OP_ACCEPT);

        //创建cpu核心数量的worker
        Worker[] workers = new Worker[Runtime.getRuntime().availableProcessors()];
        for (int i = 0; i < workers.length; i++) {
            workers[i] = new Worker("worker" + i);
            workers[i].init();
        }
        AtomicInteger index = new AtomicInteger();

        while (true) {
            log.info("等待建立连接...");
            boss.select();
            Set<SelectionKey> keys = boss.selectedKeys();
            Iterator<SelectionKey> iterator = keys.iterator();
            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                iterator.remove();
                if (key.isAcceptable()) {
                    SocketChannel sc = ssc.accept();
                    sc.configureBlocking(false);
                    //关联sc给worker里的selector
                    workers[index.getAndIncrement() % workers.length].register(sc, SelectionKey.OP_READ, null);
                    log.info("同客户端{}建立了连接", sc);
                }
            }
        }
    }
}
